<?php

class InternalLibBooleanOperators implements CliLibrary
{
	private static $operators = array(
		ExpOperator::TYPE_PREFIX => array(
			'!' => array(PREC_PREFIX, 'op_logic_not', '!p'),
			'not' => array(PREC_PREFIX, 'op_logic_not'),
		),
		ExpOperator::TYPE_LEFT => array(
			'&&' => array(PREC_LOGICAND, 'op_logic_and'),
			'and' => array(PREC_LOGICAND, 'op_numeric_and'),
			'^^' => array(PREC_LOGICXOR, 'op_logic_xor'),
			'||' => array(PREC_LOGICOR, 'op_logic_or'),
			'or' => array(PREC_LOGICOR, 'op_numeric_or'),
		),
	);

	public static function addLibrary (CliMode $mode)
	{
		$mode->addOperators(__CLASS__, self::$operators);
	}

	public static function op_logic_not (ArgContext $args)
	{
		$args->operandCount(1);
		return !$args->toBool(0);
	}

	public static function op_logic_and (ArgContext $args)
	{
		$args->operandCount(2);
		return $args->toBool(0) && $args->toBool(1);
	}

	public static function op_numeric_and (ArgContext $args)
	{
		$args->operandCount(2);
		return $args->toBool(0) && $args->toBool(1)
			? $args[1] : $args[0];
	}

	public static function op_logic_xor (ArgContext $args)
	{
		$args->operandCount(2);
		return $args->toBool(0) xor $args->toBool(1);
	}

	public static function op_logic_or (ArgContext $args)
	{
		$args->operandCount(2);
		return $args->toBool(0) || $args->toBool(1);
	}

	public static function op_numeric_or (ArgContext $args)
	{
		$args->operandCount(2);
		return $args->toBool(0) ? $args[0] : $args[1];
	}
}